//
//  DialogUpgradeVC.swift
//  SDKDebuggingDemo
//
//  Created by 秦晟哲 on 2019/8/1.
//  Copyright © 2019 QinszQSZ. All rights reserved.
//

import UIKit

class DialogUpgradeVC: UIViewController {

    @IBOutlet weak var processView: UITextView!
    
    let bleShell = KCTSingleBLEShell.sharedInstance
    
    var firmware:KCTFirmwareInfos?
    
//    var fileData:Data?
    var fileDataSerials = Array<Data>.init()
    var sendIndex:Int = 0
    
    var sendTimer:Timer?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    @IBAction func clickBack(_ sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }
    
    @IBAction func clickStart(_ sender: Any) {
        SVProgressHUD.show(withStatus: "获取固件信息...")
        self.processView.text = nil
        let firmwareTask = KCTOldBLETaskReadFirmwareInfos.init {[weak self] (tsk, error, infosModel) in
            if let err = error{
                SVProgressHUD.showError(withStatus: "获取固件信息失败")
                self?.processView.text = "获取固件信息失败:" + err.description
            }else{
                if let model = infosModel {
                    
                    if model.platform == 1 {
                        self?.firmware = model
                        
                        self?.requestFirmwareVersionInfos(serialsNum: model.serialNumber)
                    }else{
                        SVProgressHUD.showError(withStatus: "固件平台错误")
                        self?.processView.text = "固件平台错误:\(model.platform)"
                    }
                }else {
                    SVProgressHUD.showError(withStatus: "获取固件信息失败")
                    self?.processView.text = "获取固件信息失败: firmware为空"
                }
            }
        }
        bleShell.resume(baseTask: firmwareTask)
    }
    
    
    //MARK: - Step_02 获取固件升级资源包版本信息
    func requestFirmwareVersionInfos(serialsNum:Int) {
        
        SVProgressHUD.show(withStatus: "获取固件版本...")
        
        guard let serialsNum = self.firmware?.serialNumber  else {
            SVProgressHUD.showError(withStatus: "请求升级包缺少固件信息")
            print("请求升级包缺少固件信息")
            self.processView.text = "请求升级包缺少固件信息"
            self._clearTempInfos()
            return
        }
        
        let versionTask = KCTHTTPSession.share.FirmwareInfoTask(fromProduct: false, appKey: TestAPPKey, secretKey: TestSecretKey, adaptiveNum: serialsNum) {[weak self] (infos, error) in
            
            DispatchQueue.main.async {
                
                if let err = error {
                    IPrint("\(err)\n")
                    self?.processView.text = err.description
                    SVProgressHUD.showError(withStatus: err.description)
                    self?._clearTempInfos()
                    return
                }
                
                
                guard let `infos` = infos else{
                    // 没有固件信息
                    IPrint("线上没有固件信息（适配号=\(serialsNum)）")
                    SVProgressHUD.dismiss()
                    self?.processView.text = "线上没有固件信息（适配号=\(serialsNum)）"
                    self?._clearTempInfos()
                    return
                }
                
                //请求资源包
                self?.requestFirmwareFile(fileUrl: infos.file)
            }
        }
        versionTask?.resume()
    }

    //MARK: - Step_03 获取固件升级资源文件
    func requestFirmwareFile(fileUrl:String){
        
        SVProgressHUD.show(withStatus: "获取固件升级文件...")
        if let url = URL.init(string: fileUrl){
            let request = URLRequest.init(url: url)
            let session = URLSession.shared
            let task = session.dataTask(with: request) {[weak self] (data, rsp, error) in
                DispatchQueue.main.sync {
                    
                    if let `data` = data{
                        if let mimeType = rsp?.mimeType?.contains("zip"), mimeType == true {
                            self?.startFirmwareUpdate(data: data)
                            
                        }else{
                            let errInfos = "mimeType不含zip，mimeType=\(rsp?.mimeType ?? "为空")"
                            SVProgressHUD.showError(withStatus: errInfos)
                            print("\(errInfos)\n")
                            self?.processView.text = errInfos
                            self?._clearTempInfos()
                        }
                    }else{
                        let errInfos = "获取固件升级文件失败"
                        SVProgressHUD.showError(withStatus: errInfos)
                        print("\(errInfos)\n")
                        self?.processView.text = errInfos
                        self?._clearTempInfos()
                    }
                    
                    
                }
            }
            task.resume()
        }else{
            let errInfos = "初始化固件地址URL错误:urlstr = \(fileUrl)"
            SVProgressHUD.showError(withStatus: errInfos)
            print("\(errInfos)\n")
            self.processView.text = errInfos
            self._clearTempInfos()
        }
    }

    //MARK: -开始升级
    func startFirmwareUpdate(data:Data) {
        SVProgressHUD.show(withStatus: "启动升级...")
        
        if data.count < 64 {
            let errInfos = "升级包不足64字节"
            SVProgressHUD.showError(withStatus: errInfos)
            print("\(errInfos)\n")
            self.processView.text = errInfos
            self._clearTempInfos()
            return
        }
        
        //初始化dataSerials
        fileDataSerials.removeAll()
        let headData = data.subdata(in: Range.init(NSMakeRange(0, 64))!)
        fileDataSerials.append(headData)
        
        var restSerials = Array<Data>.init()
        if data.count > 64 {
            let restData = data.subdata(in: Range.init(NSMakeRange(64, data.count-64))!)
            restSerials = _splitData(data: restData, upperlimit: 20)
            fileDataSerials.append(contentsOf: restSerials)
        }
        
        
        let startTask = KCTOldBLETaskFirmwareUpdate.init(dialogHeadData: fileDataSerials.first!) {[weak self] (tsk, error, success) in
            
            if let err = error {
                SVProgressHUD.showError(withStatus: "启动升级失败")
                self?.processView.text = "启动升级失败:" + err.description
                self?._clearTempInfos()
            }else{
                //error为空则认为成功,开始发送余下的部分
                
                //将bleShell切换到rawData模式
                self?.bleShell.workMode = .RawBLEData
                
                //从serialsData的第1个包开始发送
                self?.sendIndex = 1
                let timer = Timer.init(timeInterval: 0.1, target: self, selector: #selector(self?.sendFirmwareFileData(timer:)), userInfo:nil, repeats: true)
                self?.sendTimer = timer
                RunLoop.main.add(timer, forMode: .default)
            }
        }
        bleShell.resume(baseTask: startTask)
    }
    
    @objc func sendFirmwareFileData(timer:Timer) {
        
        if self.sendIndex < self.fileDataSerials.count {
            if bleShell.isShakedHands{
                
                let progressInfos = "\(self.sendIndex)/\(self.fileDataSerials.count)"
                SVProgressHUD.show(withStatus: progressInfos)
                self.processView.text = progressInfos
                
                bleShell.writeValueForServiceCharacteristic(value: self.fileDataSerials[self.sendIndex])
                
                if self.sendIndex == self.fileDataSerials.count - 1 {
                    //发完最后一个包，升级结束
                    let infos = "升级完成!"
                    print("\(infos)\n")
                    SVProgressHUD.showSuccess(withStatus: infos)
                    self.processView.text = infos
                    self._clearTempInfos()
                }else{
                    //index加1，等待待定时器下一次的调用
                    self.sendIndex = self.sendIndex + 1
                }
            }else{
                //没有握手，终止
                let errInfos = "发送数据时，检测到连接中断了:fileDataSerials.count=\(fileDataSerials.count),sendIndex=\(sendIndex)"
                print("\(errInfos)\n")
                SVProgressHUD.showError(withStatus: errInfos)
                self.processView.text = errInfos
                
                timer.invalidate()
                self.sendTimer = nil
            }
        }else{
            let errInfos = "包序号异常:fileDataSerials.count=\(fileDataSerials.count),sendIndex=\(sendIndex)"
            print("\(errInfos)\n")
            SVProgressHUD.showError(withStatus: errInfos)
            self.processView.text = errInfos
            timer.invalidate()
            self.sendTimer = nil
        }

    }
    
    func _clearTempInfos() {
        self.firmware = nil
        self.fileDataSerials.removeAll()
    }
    
    
    
    public func _splitData(data:Data,upperlimit:Int) -> Array<Data> {
        if upperlimit <= 0{
            return [data]
        }else{
            var dataArray = Array<Data>.init()
            var restData = data
            while restData.count > upperlimit {
                let range = Range.init(NSMakeRange(0, upperlimit))!
                let sliceData = restData.subdata(in: range)
                dataArray.append(sliceData)
                let restRange = Range.init(NSMakeRange(sliceData.count, restData.count - sliceData.count))!
                restData = restData.subdata(in: restRange)
            }
            
            dataArray.append(restData)
            
            return dataArray
        }
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
